﻿using System;
using UnityEngine;

namespace CGF
{
    public static class TimeHelper
    {
        /// <summary>
        /// 返回秒，需要毫秒可调用 GetLocalTimestampMS()
        /// </summary>
        public static int GetLocalTimestampS()
        {
            TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
            return Convert.ToInt32(ts.TotalSeconds);
        }

        /// <summary>
        /// 返回毫秒，需要秒可调用 GetLocalTimestamp()
        /// </summary>
        public static long GetLocalTimestampMS()
        {
            TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
            return Convert.ToInt64(ts.TotalMilliseconds);
        }

        /// <summary>
        /// DateTime转时间戳(秒)
        /// </summary>
        public static int DateTimeToTimestampS(DateTime time)
        {
            DateTime startTime = new DateTime(1970, 1, 1, 0, 0, 0, 0);
            return Convert.ToInt32((time - startTime).TotalSeconds);
        }

        /// <summary>
        /// 时间戳换DateTime
        /// </summary>
        public static DateTime TimestampSToDateTime(long seconds)
        {
            DateTime startTime = new DateTime(1970, 1, 1, 0, 0, 0, 0);
            DateTime time = startTime.AddSeconds(seconds).AddHours(8);
            return time;
        }

        /// <summary>
        /// 时间戳换DateTime
        /// </summary>
        public static DateTime TimeSpanToDateTime(TimeSpan timeSpan)
        {
            return TimestampSToDateTime(Convert.ToInt64(timeSpan.TotalSeconds));
        }

        /// <summary>
        /// 字符串形式转DateTime
        /// </summary>
        /// <returns></returns>
        public static DateTimeOffset StringToDateTime(string time)
        {
            return DateTimeOffset.Parse(time);
        }
        
        /// <summary>
        /// 字符串形式转DateTime(UTC时间)
        /// </summary>
        /// <returns></returns>
        public static DateTime StringToDateTimeUTC(string time)
        {
            DateTime dateTime = DateTime.Parse(time);
            return dateTime.ToUniversalTime();
        }

        /// <summary>
        /// 延迟执行一个方法
        /// </summary>
        public static async void Invoke(float delay, Action action)
        {
            if (delay > 0)
            {
                await CTask.Wait(delay);
            }
            action?.Invoke();
        }

        /// <summary>
        /// 延迟重复执行一个方法
        /// </summary>
        /// <param name="delay">延迟开始</param>
        /// <param name="action">方法回调</param>
        /// <param name="interval">每次间隔</param>
        /// <param name="times">次数，小于等于0表示无限</param>
        /// <returns>返回CTask，调用CTask的Dispose方法提前停止</returns>
        public static async CTask InvokeRepeat(float delay, Action action, float interval, int times = 0)
        {
            if (interval <= 0)
            {
                Debug.LogError("参数 interval 必须大于0");
                return;
            }
            if (delay > 0)
            {
                await CTask.Wait(delay);
            }
            if (times <= 0)
            {
                while (true)
                {
                    action?.Invoke();
                    await CTask.Wait(interval);
                }
            }
            else
            {
                for (int i = 0; i < times; i++)
                {
                    action?.Invoke();
                    await CTask.Wait(interval);
                }
            }
        }

        /// <summary>
        /// 当前系统是否是中国时区
        /// </summary>
        public static bool IsChinaTimeZone()
        {
            return TimeZoneInfo.Local.Id == "China Standard Time";
        }

        /// <summary>
        /// 当前系统是否是印度时区
        /// </summary>
        public static bool IsIndiaTimeZone()
        {
            return TimeZoneInfo.Local.Id == "India Standard Time";
        }

        /// <summary>
        /// 月份数字转英文
        /// </summary>
        public static string MonthName(int month)
        {
            switch (month)
            {
                case 1: return "Jan";
                case 2: return "Feb";
                case 3: return "Mar";
                case 4: return "Apr";
                case 5: return "May";
                case 6: return "Jun";
                case 7: return "Jul";
                case 8: return "Aug";
                case 9: return "Sep";
                case 10: return "Oct";
                case 11: return "Nov";
                case 12: return "Dec";
            }
            return null;
        }

        /// <summary>
        /// 月份英文缩写转数字
        /// </summary>
        public static int MonthNum(string monthName)
        {
            switch (monthName)
            {
                case "Jan": return 1;
                case "Feb": return 2;
                case "Mar": return 3;
                case "Apr": return 4;
                case "May": return 5;
                case "Jun": return 6;
                case "Jul": return 7;
                case "Aug": return 8;
                case "Sep": return 9;
                case "Oct": return 10;
                case "Nov": return 11;
                case "Dec": return 12;
            }
            return 0;
        }

        public static string Parse2Date(string dateTime, bool includeYear)
        {
            return Parse2Date(DateTimeOffset.Parse(dateTime), includeYear);
        }

        public static string Parse2Date(DateTimeOffset dateTime, bool includeYear)
        {
            string format;
            switch (I18N.CurrLanguage)
            {
                case ELanguage.ZH_CN:
                default:
                    format = includeYear ? "yyyy-MM-dd" : "MM-dd";
                    break;
                case ELanguage.EN_US:
                    format = includeYear ? "MM/dd/yyyy" : "MM/dd";
                    break;
                case ELanguage.PT_BR:
                    format = includeYear ? "dd/MM/yyyy" : "dd/MM";
                    break;
                case ELanguage.VI_VN:
                    format = includeYear ? "dd/MM/yyyy" : "dd/MM";
                    break;
            }
            return dateTime.ToString(format);
        }
        
        public static string Parse2Time(string dateTime, bool includeaDate)
        {
            return Parse2Time(DateTimeOffset.Parse(dateTime), includeaDate);
        }

        public static string Parse2Time(DateTimeOffset dateTime, bool includeaDate)
        {
            string format;
            switch (I18N.CurrLanguage)
            {
                case ELanguage.ZH_CN:
                default:
                    format = includeaDate ? "yyyy-MM-dd HH:mm:ss" : "HH:mm:ss";
                    break;
                case ELanguage.EN_US:
                    format = includeaDate ? "HH:mm:ss MM/dd/yyyy" : "HH:mm:ss";
                    break;
                case ELanguage.PT_BR:
                    format = includeaDate ? "HH:mm:ss dd/MM/yyyy" : "HH:mm:ss";
                    break;
                case ELanguage.VI_VN:
                    format = includeaDate ? "HH:mm:ss dd/MM/yyyy" : "HH:mm:ss";
                    break;
            }
            return dateTime.ToString(format);
        }
    }
}
